[BZOJ2435] [Noi2011]道路修建

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=2435

题目大意

给定一棵树,对于每一条边,对于答案的贡献为边长*abs(所连两点两边的点数差)

题解

任取个点转成有根树,BFS一次,得到每个点自己和子节点的个数和,我们知道,对于每条边所连两个点,一定是父节点和子节点,所以子节点下面的节点数一定比父节点少,知道子节点数a,剩下的点数就是n-a,然后计算即可

var
 w:array[0..3000000,1..3]of longint;
 x,y:array[0..1000000]of longint;
 t:array[0..1000000,1..2]of longint;
 z:array[0..1000000,1..3]of longint;
 i,j,k:longint;
 n,len,tail,tt:longint;
 a,b,c:longint;
 ans:int64;
procedure init(a,b,c:longint);
begin
 w[len,1]:=b; w[len,2]:=c;
 if w[a,3]=0
 then w[a,3]:=len else w[w[a,1],3]:=len;
 w[a,1]:=len; inc(len);
end;

begin
 readln(n); len:=n+1; ans:=0;
 for i:=1 to n-1 do
  begin readln(a,b,c); init(a,b,c); init(b,a,c); z[i,1]:=a; z[i,2]:=b; z[i,3]:=c; end;
 fillchar(y,sizeof(y),0);
 t[1,1]:=1; t[1,2]:=0; tail:=1; y[1]:=1;
 for i:=1 to n do
  begin
   tt:=w[t[i,1],3];
   while tt<>0 do
    begin
     if y[w[tt,1]]=0
     then begin inc(tail); t[tail,1]:=w[tt,1]; t[tail,2]:=t[i,1]; y[w[tt,1]]:=1; end;
     tt:=w[tt,3];
    end;
  end;
 for i:=1 to n do
  x[i]:=1;
 for i:=n downto 1 do
  inc(x[t[i,2]],x[t[i,1]]);
 for i:=1 to n-1 do
  begin
   a:=z[i,1]; b:=z[i,2]; c:=z[i,3];
   if x[a]<x[b] then j:=x[a] else j:=x[b];
   k:=n-j; a:=abs(k-j);
   inc(ans,int64(a)*int64(c));
  end;
 writeln(ans);
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值